//C++STL中的哈希表有两种unordered_set和unordered_map


//////unordered_set的介绍

//1.unordered_set是不按特定顺序存储键值的关联式容器，其允许通过键值快速的索引到对应的元素。
//2.在unordered_set中，元素的值同时也是唯一地标识它的key。
//3.在内部，unordered_set中的元素没有按照任何特定的顺序排序，为了能在常数范围内找到指定的key，unordered_set将相同哈希值的键值放在相同的桶中。
//4.unordered_set容器通过key访问单个元素要比set快，但它通常在遍历元素子集的范围迭代方面效率较低。
//5.它的迭代器至少是前向迭代器。


#include<unordered_set>

//定义方式

unordered_set<int> us1;                             //构造int类型空容器

unordered_set<int> us2(us1);                        //拷贝构造


string str("abcdefg");
unordered_set<char> us3(str.begin(), str.end());    //使用迭代器拷贝构造


//接口包括成员函数和迭代器相关函数

//成员函数
/*
.insert	插入指定元素
.erase	删除指定元素
.find	查找指定元素
.size	获取容器中元素的个数
.empty	判断容器是否为空
.clear	清空容器
.swap	交换两个容器中的数据
.count	获取容器中指定元素值的元素个数
*/


//示例:
#include <iostream>
#include <unordered_set>
using namespace std;

int main()
{
	unordered_set<int> us;
	//插入元素（去重）
	us.insert(1);
	us.insert(4);
	us.insert(3);
	us.insert(3);
	us.insert(2);
	us.insert(2);
	us.insert(3);
	//遍历容器方式一（范围for）
	for (auto e : us)
	{
		cout << e << " ";
	}
	cout << endl; //1 4 3 2
	//删除元素方式一
	us.erase(3);                //直接删除元素
	//删除元素方式二
	unordered_set<int>::iterator pos = us.find(1); //查找值为1的元素,返回迭代器位置,不存在返回us.end()
	if (pos != us.end())        //.end()表示容器末尾位置，不指向任何元素
	{
		us.erase(pos);          //删除迭代器
	}
	//遍历容器方式二（迭代器遍历）
	unordered_set<int>::iterator it = us.begin();
	while (it != us.end())
	{
		cout << *it << " ";
		it++;
	}
	cout << endl; //4 2
	//容器中值为2的元素个数
	cout << us.count(2) << endl; //1
	//容器大小
	cout << us.size() << endl; //2
	//清空容器
	us.clear();
	//容器判空
	cout << us.empty() << endl; //1
	//交换两个容器的数据
	unordered_set<int> tmp{ 11, 22, 33, 44 };
	us.swap(tmp);
	for (auto e : us)
	{
		cout << e << " ";
	}
	cout << endl; //11 22 33 44
	return 0;
}

//unordered_multiset
//unordered_multiset容器与unordered_set容器的底层数据结构是一样的，都是哈希表，其次，它们所提供的成员函数的接口都是基本一致的，这里就不再列举了，这两种容器唯一的区别就是，unordered_multiset容器允许键值冗余，即unordered_multiset容器当中存储的元素是可以重复的。












////////unordered_map的介绍
//1.unordered_map是存储<key, value>键值对的关联式容器，其允许通过key值快速的索引到与其对应是value。
//2.在unordered_map中，键值通常用于唯一地标识元素，而映射值是一个对象，其内容与此键关联。键和映射值的类型可能不同。
//3.在内部，unordered_map没有对<key, value>按照任何特定的顺序排序，为了能在常数范围内找到key所对应的value，unordered_map将相同哈希值的键值对放在相同的桶中。
//4.unordered_map容器通过key访问单个元素要比map快，但它通常在遍历元素子集的范围迭代方面效率较低。
//5.unordered_map实现了直接访问操作符（operator[]），它允许使用key作为参数直接访问value。
//6.它的迭代器至少是前向迭代器。


//unordered_map的定义方式
//方式一： 指定key和value的类型构造一个空容器。
unordered_map<int, double> um1; 								//构造一个key为int类型，value为double类型的空容器

//方式二： 拷贝构造某同类型容器的复制品。
unordered_map<int, double> um2(um1); 							//拷贝构造

//方式三： 使用迭代器拷贝构造某一段内容。
unordered_map<int, double> um3(um2.begin(), um2.end()); 		//使用迭代器拷贝构造um2容器某段区间的复制品



//成员函数
//insert	插入键值对
//erase	删除指定key值的键值对
//find	查找指定key值的键值对
//size	获取容器中元素的个数
//empty	判断容器是否为空
//clear	清空容器
//swap	交换两个容器中的数据
//count	获取容器中指定key值的元素个数


//除了上述的成员函数之外，unordered_map容器当中还实现了[ ]运算符重载函数，该重载函数的功能非常强大：[key]

//若当前容器中已有键值为key的键值对，则返回该键值对value的引用。
//若当前容器中没有键值为key的键值对，则先插入键值对<key, value()>，然后再返回该键值对中value的引用。

